const styles = (v = '') =>
  v
    .split(';')
    .filter((v) => v && !/^[\n\s]+$/.test(v))
    .map((v) => {
      const key = v.slice(0, v.indexOf(':'))
      const value = v.slice(v.indexOf(':') + 1)
      return {
        [key
          .replace(/-([a-z])/g, function () {
            return arguments[1].toUpperCase()
          })
          .replace(/\s+/g, '')]:
          value.replace(/^\s+/, '').replace(/\s+$/, '') || ''
      }
    })
export function parent(parent) {
  return {
    provide() {
      return {
        [parent]: this
      }
    },
    data() {
      return {
        el: {
          css: {},
          views: []
        }
      }
    },
    watch: {
      css: {
        handler(v) {
          if (this.canvasId) {
            this.el.css =
              (typeof v === 'object' ? v : v && Object.assign(...styles(v))) ||
              {}
            this.canvasWidth =
              (this.el.css && this.el.css.width) || this.canvasWidth
            this.canvasHeight =
              (this.el.css && this.el.css.height) || this.canvasHeight
          }
        },
        immediate: true
      }
    }
  }
}
export function children(parent, options = {}) {
  const indexKey = options.indexKey || 'index'
  return {
    inject: {
      [parent]: {
        default: null
      }
    },
    watch: {
      el: {
        handler(v, o) {
          if (JSON.stringify(v) != JSON.stringify(o)) { 
            this.bindRelation()
           }
        },
        deep: true,
        immediate: true
      },
      src: {
        handler(v, o) {
          if (v != o) { 
            this.bindRelation()
           }
        },
        immediate: true
      },
      text: {
        handler(v, o) {
          if (v != o) this.bindRelation()
        },
        immediate: true
      },
      css: {
        handler(v, o) {
          if (v != o)
            {this.el.css =
              (typeof v == 'object' ? v : v && Object.assign(...styles(v))) ||
              {}}
        },
        immediate: true
      },
      replace: {
        handler(v, o) {
          if (JSON.stringify(v) != JSON.stringify(o)) { 
            this.bindRelation()
           }
        },
        deep: true,
        immediate: true
      }
    },
    created() {
      if (!this._uid) {
        this._uid = this._.uid
      }
      Object.defineProperty(this, 'parent', {
        get: () => this[parent] || []
      })
      Object.defineProperty(this, 'index', {
        get: () => {
          this.bindRelation()
          const { parent: { el: { views = [] } = {} } = {} } = this
          return views.indexOf(this.el)
        }
      })
      this.el.type = this.type

      this.bindRelation()
    },
    // #ifdef VUE3
    beforeUnmount() {
      this.removeEl()
    },
    // #endif
    // #ifdef VUE2
    beforeDestroy() {
      this.removeEl()
    },
    // #endif
    methods: {
      removeEl() {
        if (this.parent) {
          this.parent.el.views = this.parent.el.views.filter(
            (item) => item._uid !== this._uid
          )
        }
      },
      bindRelation() {
        if (!this.el._uid) {
          this.el._uid = this._uid
        }
        if (['text', 'qrcode'].includes(this.type)) {
          this.el.text =
            (this.$slots &&
              this.$slots.default &&
              this.$slots.default[0].text) ||
            `${this.text || ''}`.replace(/\\n/g, '\n')
        }
        if (this.type == 'image') {
          this.el.src = this.src
        }
        if (!this.parent) {
          return
        }
        const views = this.parent.el.views || []
        if (views.indexOf(this.el) !== -1) {
          this.parent.el.views = views.map((v) =>
            v._uid == this._uid ? this.el : v
          )
        } else {
          this.parent.el.views = [...views, this.el]
        }
      }
    },
    mounted() {
      // this.bindRelation()
    }
  }
}
